package token

import (
	"encoding/json"
	"time"

	"gitee.com/keepalived_0807/Vblog/apps/user"
	"github.com/rs/xid"
)

type Token struct {
	// 该Token是谁颁发
	UserId int `json:"user_id" gorm:"column:user_id"`
	// 人的名称， user_name
	Username string `json:"user_name" gorm:"column:username"`
	// 颁发给用户的访问令牌
	AccessToken string `json:"access_token" gorm:"column:access_token"`
	// 刷新令牌过期时间
	RefreshToken string `json:"refresh_token" gorm:"column:refresh_token"`
	// 访问令牌过期时间
	AccessTokenExpiredAt int `json:"access_token_expired_at" gorm:"column:access_token_expired_at"`
	// 刷新令牌过期时间
	RefreshTokenExpiredAt int `json:"refresh_token_expired_at" gorm:"column:refresh_token_expired_at"`
	// 创建时间
	CreatedAt int64 `json:"created_at" gorm:"column:created_at"`
	// 更新时间
	UpdatedAt int64 `json:"updated_at" gorm:"column:updated_at"`
	// 角色
	Role user.Role `json:"role" gorm:"-"`
}

func (t *Token) IssueTime() time.Time {
	return time.Unix(t.CreatedAt, 0)
}

func (t *Token) AccessTokenDuration() time.Duration {
	return time.Duration(t.AccessTokenExpiredAt * int(time.Second))
}

func (t *Token) RefreshTokenDuration() time.Duration {
	return time.Duration(t.RefreshTokenExpiredAt * int(time.Second))
}

func (t *Token) AccessTokenIsExpired() error {
	// 算出过期时间: 颁发时间 + 过期时长
	expiredTime := t.IssueTime().Add(t.RefreshTokenDuration())
	// fmt.Println(time.Since(expiredTime).Seconds())
	if time.Since(expiredTime).Seconds() > 0 {
		return ErrAccessTokenExpired
	}
	return nil
}

func (t *Token) RefreshTokenIsExpired() error {
	expiredTime := t.IssueTime().Add(t.RefreshTokenDuration())
	// fmt.Println(time.Since(expiredTime).Seconds())
	if time.Since(expiredTime).Seconds() > 0 {
		return ErrRefreshTokenExpired
	}
	return nil
}

func DefaultToken() *Token {
	return &Token{}
}

func NewToken(u *user.User) *Token {
	return &Token{
		UserId:                u.Id,
		Username:              u.Username,
		AccessToken:           xid.New().String(),
		AccessTokenExpiredAt:  3600,
		RefreshToken:          xid.New().String(),
		RefreshTokenExpiredAt: 3600 * 4,
		CreatedAt:             time.Now().Unix(),
		Role:                  u.Role,
	}
}

func (t *Token) String() string {
	dj, _ := json.MarshalIndent(t, "", "	")
	return string(dj)
}
